#!/bin/bash

# ANSI颜色代码
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BLUE='\033[0;34m'
PURPLE='\033[0;35m'
NC='\033[0m' # 无颜色

# 获取当前系统框架信息
function get_system_framework() {
    # 检查操作系统
    if [[ -f /etc/redhat-release ]]; then
        release="centos"
    elif cat /etc/issue | grep -Eqi "debian"; then
        release="debian"
    elif cat /etc/issue | grep -Eqi "ubuntu"; then
        release="ubuntu"
    elif cat /etc/issue | grep -Eqi "centos|red hat|redhat"; then
        release="centos"
    elif cat /proc/version | grep -Eqi "debian"; then
        release="debian"
    elif cat /proc/version | grep -Eqi "ubuntu"; then
        release="ubuntu"
    elif cat /proc/version | grep -Eqi "centos|red hat|redhat"; then
        release="centos"
    else
        echo -e "${RED}未检测到系统版本，请联系脚本作者！${NC}\n"
        exit 1
    fi

    # 获取架构
    arch=$(arch)

    if [[ $arch == "x86_64" || $arch == "x64" || $arch == "s390x" || $arch == "amd64" ]]; then
        arch="amd64"
    elif [[ $arch == "aarch64" || $arch == "arm64" ]]; then
        arch="arm64"
    else
        arch="amd64"
        echo -e "${RED}检测架构失败，使用默认架构: ${arch}${NC}"
    fi

    # 获取操作系统版本
    os_version=""
    if [[ -f /etc/os-release ]]; then
        os_version=$(awk -F'[= ."]' '/VERSION_ID/{print $3}' /etc/os-release)
    fi
    if [[ -z "$os_version" && -f /etc/lsb-release ]]; then
        os_version=$(awk -F'[= ."]+' '/DISTRIB_RELEASE/{print $2}' /etc/lsb-release)
    fi

    # 打印系统框架信息
    echo -e "${GREEN}系统框架信息:${NC}"
    echo -e "${YELLOW}操作系统: ${release}${NC}"
    echo -e "${YELLOW}架构: ${arch}${NC}"
    echo -e "${YELLOW}操作系统版本: ${os_version}${NC}"
}

# 获取x-ui面板信息
function get_xui_info() {
    echo -e "${YELLOW}正在获取 x-ui 面板信息，请稍候...${NC}"

    # 在后台运行 x-ui 命令并获取输出
    output=$(echo -e "7\n" | x-ui 2>&1)

    # 从输出中提取面板端口、路径、用户名和密码信息
    XUI_PORT=$(echo "$output" | grep -oP '监听端口\[port\]: \K\d+')
    XUI_PATH=$(echo "$output" | grep -oP '根路径\[basePath\]: \K/[^/]+' | sed 's/^.//')
    XUI_USERNAME=$(echo "$output" | grep -oP '用户名\[username\]: \K\w+')
    XUI_PASSWORD=$(echo "$output" | grep -oP '密码\[userpasswd\]: \K\w+')

    # 打印提取的信息
    echo -e "${GREEN}面板信息已获取:${NC}"
    echo -e "${BLUE}面板端口: ${PURPLE}$XUI_PORT${NC}"
    echo -e "${BLUE}根路径: ${PURPLE}$XUI_PATH${NC}"
    echo -e "${BLUE}用户名: ${PURPLE}$XUI_USERNAME${NC}"
    echo -e "${BLUE}密码: ${PURPLE}$XUI_PASSWORD${NC}"
}

# 登录x-ui面板
function login() {
    # 获取主机IP
    HOST_IP=$(curl -s http://ipinfo.io/ip)

    # 检查主机IP是否获取成功
    if [ -z "$HOST_IP" ]; then
        echo -e "${RED}无法获取主机IP，请检查网络连接。${NC}"
        exit 1
    fi

    # 定义登录请求的URL
    LOGIN_URL="http://$HOST_IP:$XUI_PORT/login"

    # 定义登录请求头参数
    LOGIN_HEADERS=(
      "Host: $HOST_IP:$XUI_PORT"
      "Connection: keep-alive"
      "Content-Length: 34"
      "Accept: application/json, text/plain, */*"
      "X-Requested-With: XMLHttpRequest"
      "User-Agent: Mozilla/5.0 (Linux; Android 13; 23049RAD8C Build/TKQ1.221114.001) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.5359.128 Mobile Safari/537.36"
      "Content-Type: application/x-www-form-urlencoded; charset=UTF-8"
      "Origin: http://$HOST_IP:$XUI_PORT"
      "Referer: http://$HOST_IP:$XUI_PORT/"
      "Accept-Encoding: gzip, deflate"
      "Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7"
    )

    # 发送登录请求并提取Set-Cookie头中的session值
    LOGIN_DATA="username=$XUI_USERNAME&password=$XUI_PASSWORD"
    RESPONSE=$(curl -X POST -H "${LOGIN_HEADERS[@]}" -d "$LOGIN_DATA" "$LOGIN_URL" --insecure -i 2>/dev/null)
    SESSION_COOKIE=$(echo "$RESPONSE" | grep -i 'Set-Cookie:' | sed -n 's/.*session=\([^;]*\).*/\1/p')
    if [ -z "$SESSION_COOKIE" ]; then
        echo -e "${RED}登录失败，请检查x-ui面板登录账号和密码。${NC}"
        return 1
    else
        echo -e "${GREEN}登录成功！${NC}"
        return 0
    fi
}

# 更新面板配置
function update_panel_config() {
    # 获取主机IP
    HOST_IP=$(curl -s http://ipinfo.io/ip)

    # 检查主机IP是否获取成功
    if [ -z "$HOST_IP" ]; then
        echo -e "${RED}无法获取主机IP，请检查网络连接。${NC}"
        exit 1
    fi

    # 定义面板配置更新请求的 URL
    UPDATE_URL="http://$HOST_IP:$XUI_PORT/xui/setting/update"

    # 定义请求头参数
    UPDATE_HEADERS=(
      "Host: $HOST_IP:$XUI_PORT"
      "Connection: keep-alive"
      "Content-Length: 3080"  # 将在构建请求体后更新
      "Accept: application/json, text/plain, */*"
      "X-Requested-With: XMLHttpRequest"
      "User-Agent: Mozilla/5.0 (Linux; Android 13; 23049RAD8C Build/TKQ1.221114.001) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.5359.128 Mobile Safari/537.36"
      "Content-Type: application/x-www-form-urlencoded; charset=UTF-8"
      "Origin: http://$HOST_IP:$XUI_PORT"
      "Referer: http://$HOST_IP:$XUI_PORT/xui/setting"
      "Accept-Encoding: gzip, deflate"
      "Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7"
      "Cookie: session=$SESSION_COOKIE"
    )

    # 定义 xrayTemplateConfig 内容
    XRAY_TEMPLATE='{
      "api": {
        "services": [
          "HandlerService",
          "LoggerService",
          "StatsService"
        ],
        "tag": "api"
      },
      "inbounds": [
        {
          "listen": "127.0.0.1",
          "port": 62789,
          "protocol": "dokodemo-door",
          "settings": {
            "address": "127.0.0.1"
          },
          "tag": "api"
        }
      ],
      "outbounds": [
        {
          "protocol": "freedom",
          "settings": {}
        },
        {
          "protocol": "blackhole",
          "settings": {},
          "tag": "blocked"
        }
      ],
      "policy": {
        "levels": {
          "0": {
            "handshake": 10,
            "connIdle": 100,
            "uplinkOnly": 2,
            "downlinkOnly": 3,
            "statsUserUplink": true,
            "statsUserDownlink": true,
            "bufferSize": 10240
          }
        },
        "system": {
          "statsInboundDownlink": true,
          "statsInboundUplink": true
        }
      },
      "routing": {
        "rules": [
          {
            "inboundTag": [
              "api"
            ],
            "outboundTag": "api",
            "type": "field"
          },
          {
            "ip": [
              "geoip:private"
            ],
            "outboundTag": "blocked",
            "type": "field"
          },
          {
            "outboundTag": "blocked",
            "protocol": [
              "bittorrent"
            ],
            "type": "field"
          }
        ]
      },
      "stats": {}
    }'

    # 生成四个随机大小写字母组合
    generate_random_path() {
      tr -dc 'a-zA-Z' < /dev/urandom | head -c 4
    }

    WEB_BASE_PATH=$(generate_random_path)

    # 定义 URL 编码函数
    url_encode() {
      local raw_string="$1"
      local encoded_string=""
      for (( i=0; i<${#raw_string}; i++ )); do
        local c="${raw_string:i:1}"
        case "$c" in
          [a-zA-Z0-9.~_-]) encoded_string+="$c" ;;  # 不需要编码的字符
          *) printf -v encoded_string '%s%%%02X' "$encoded_string" "'$c" ;;  # 其他字符编码
        esac
      done
      echo "$encoded_string"
    }

    # 定义请求内容文本
    get_update_data() {
      local update_content="webListen=&webPort=$XUI_PORT&webCertFile=&webKeyFile=&webBasePath=/$WEB_BASE_PATH/&tgBotEnable=false&tgBotToken=&tgBotChatId=0&tgRunTime=&xrayTemplateConfig=$(url_encode "$XRAY_TEMPLATE")&tgNotifyExpireTimeDiff=0&tgNotifyTrafficDiff=0&cpulimitNotifyConfig=0&timeLocation=Asia/Shanghai"
      
      echo "$update_content"
    }

    # 获取请求内容
    DATA=$(get_update_data)

    # 更新 Content-Length
    CONTENT_LENGTH=${#DATA}
    UPDATE_HEADERS[2]="Content-Length: $CONTENT_LENGTH"

    # 构建 curl 命令
    CURL_CMD="curl -X POST"

    # 添加请求头参数
    for HEADER in "${UPDATE_HEADERS[@]}"; do
      CURL_CMD+=" -H \"$HEADER\""
    done

    # 添加请求内容和 URL
    CURL_CMD+=" -d \"$DATA\" \"$UPDATE_URL\" --insecure"

    # 执行更新请求的 curl 命令并捕获响应
    RESPONSE=$(eval $CURL_CMD)
    
    # 检查响应结果
    if echo "$RESPONSE" | grep -q '修改设置成功'; then
      echo -e "${GREEN}面板配置更新成功。${NC}"
    else
      echo -e "${RED}面板配置更新失败。${NC}"
    fi
}

# x-ui面板一键安装
function install_x_ui() {
    echo -e "${YELLOW}正在获取系统框架信息...${NC}"
    get_system_framework

    # 自动判断网络环境并选择下载源
    echo -e "${YELLOW}正在检测网络环境...${NC}"
    if curl -s -m 5 https://www.google.com > /dev/null; then
        echo -e "${GREEN}检测到国外网络环境，选择从 GitHub 下载。${NC}"
        download_source="github"
    else
        echo -e "${GREEN}检测到国内网络环境，选择从 Gitee 下载。${NC}"
        download_source="gitee"
    fi

    local download_url=""
    if [[ $download_source == "github" ]]; then
        echo -e "${GREEN}选择从 GitHub 下载...${NC}"
        download_url="https://github.com/FranzKafkaYu/x-ui/releases/download/0.3.4.4/x-ui-linux-${arch}.tar.gz"
    elif [[ $download_source == "gitee" ]]; then
        echo -e "${GREEN}选择从 Gitee 下载...${NC}"
        if [[ $arch == "amd64" ]]; then
            download_url="https://gitee.com/falling-down-to-be-born/xui/releases/download/0.3.4.4/x-ui-linux-amd64.tar.gz"
        elif [[ $arch == "arm64" ]]; then
            download_url="https://gitee.com/falling-down-to-be-born/xui/releases/download/arm64/x-ui-linux-arm64.tar.gz"
        elif [[ $arch == "s390x" ]]; then
            download_url="https://gitee.com/falling-down-to-be-born/xui/releases/download/s390x/x-ui-linux-s390x.tar.gz"
        else
            echo -e "${RED}不支持的架构: ${arch}${NC}"
            exit 1
        fi
    fi

    echo -e "${GREEN}开始下载 x-ui 安装包...${NC}"
    # 使用 tput 和 printf 实现动态更新一行的进度条，并显示文件累计大小
    wget -N --no-check-certificate -O /root/x-ui-linux-${arch}.tar.gz ${download_url} 2>&1 | while read line; do
        if [[ $line == *"%"* ]]; then
            # 提取进度百分比
            progress=$(echo "$line" | grep -o '[0-9]*%' | tr -d '%')
            # 提取文件累计大小（以 KB 为单位）
            size_kb=$(echo "$line" | grep -o '^[0-9]*K' | tr -d 'K')
            # 将 KB 转换为 MB
            size_mb=$(awk "BEGIN {printf \"%.2f\", $size_kb / 1024}")
            # 动态更新进度条和文件大小
            printf "\r${YELLOW}下载进度: %3s%% | 已下载: %6.2f MB${NC}" "$progress" "$size_mb"
        fi
    done
    echo -e "\n${GREEN}下载完成，文件保存在 /root/x-ui-linux-${arch}.tar.gz${NC}"

    cd /root/
    rm -rf x-ui/ /usr/local/x-ui/ /usr/bin/x-ui
    tar zxvf x-ui-linux-${arch}.tar.gz
    chmod +x x-ui/x-ui x-ui/bin/xray-linux-* x-ui/x-ui.sh
    cp x-ui/x-ui.sh /usr/bin/x-ui
    cp -f x-ui/x-ui.service /etc/systemd/system/
    mv x-ui/ /usr/local/
    systemctl daemon-reload
    systemctl enable x-ui
    systemctl restart x-ui

    echo -e "${GREEN}x-ui面板安装完成。${NC}"

    # 获取x-ui面板信息
    get_xui_info

    # 判断面板根路径是否为4位字母
    if [[ ${#XUI_PATH} -eq 4 && $XUI_PATH =~ ^[A-Za-z]+$ ]]; then
        echo -e "${GREEN}面板根路径已设置。${NC}"
    else
        echo -e "${YELLOW}正在设置面板根路径，请耐心等待...${NC}"
        if login; then
            update_panel_config
            echo -e "${GREEN}设置根路径完成。${NC}"
        else
            echo -e "${RED}登录失败，无法设置新的根路径。${NC}"
        fi
    fi

    # 重启x-ui面板
    echo -e "${YELLOW}正在重启x-ui面板...${NC}"
    systemctl restart x-ui
    echo -e "${GREEN}x-ui面板重启完成。${NC}"
}

# 配置虚拟IP并生成x-ui面板配置文件
function configure_vips() {
    # 默认的IP段
    DEFAULT_IP_PREFIX="192.168.0."

    # 提示用户输入IP段
    read -p "请输入虚拟IP固定段（默认为$DEFAULT_IP_PREFIX）: " IP_PREFIX
    IP_PREFIX=${IP_PREFIX:-$DEFAULT_IP_PREFIX}

    # 获取主网卡名称（通常为eth0）
    MAIN_NIC=$(ip route | grep default | awk 'NR==1 {print $5}')

    # 检查主网卡是否存在
    if [ -z "$MAIN_NIC" ]; then
        echo -e "${RED}主网卡未找到，请检查网络配置。${NC}"
        exit 1
    fi

    # 获取主网卡的MAC地址
    MAC_ADDRESS=$(ip link show $MAIN_NIC | grep link/ether | awk '{print $2}')

    # 检查MAC地址是否获取成功
    if [ -z "$MAC_ADDRESS" ]; then
        echo -e "${RED}无法获取主网卡的MAC地址，请检查网络配置。${NC}"
        exit 1
    fi

    # 获取子网掩码
    NETMASK=$(ifconfig $MAIN_NIC | grep -w "inet" | awk '{print $4}')

    # 检查子网掩码是否获取成功
    if [ -z "$NETMASK" ]; then
        echo -e "${RED}无法获取子网掩码，请检查网络配置。${NC}"
        exit 1
    fi

    # 获取默认网关
    GATEWAY=$(ip route | grep default | awk 'NR==1 {print $3}')

    # 检查默认网关是否获取成功
    if [ -z "$GATEWAY" ]; then
        echo -e "${RED}无法获取默认网关，请检查网络配置。${NC}"
        exit 1
    fi

    # 默认虚拟IP地址的最后一段
    DEFAULT_START_IP=11

    # 默认需要配置的虚拟IP数量
    DEFAULT_IP_COUNT=9

    # 默认起始端口
    DEFAULT_START_PORT=51

    # 提示用户输入起始IP地址的最后一段
    read -p "请输入虚拟IP地址的最后一段（默认为$DEFAULT_START_IP）: " START_IP
    START_IP=${START_IP:-$DEFAULT_START_IP}

    # 提示用户输入需要配置的虚拟IP数量
    read -p "请输入需要配置的虚拟IP数量（默认为$DEFAULT_IP_COUNT）: " IP_COUNT
    IP_COUNT=${IP_COUNT:-$DEFAULT_IP_COUNT}

    # 提示用户输入起始端口
    read -p "请输入起始端口（默认为$DEFAULT_START_PORT）: " START_PORT
    START_PORT=${START_PORT:-$DEFAULT_START_PORT}

    # 检查输入是否为数字
    if ! [[ "$START_IP" =~ ^[0-9]+$ ]] || ! [[ "$IP_COUNT" =~ ^[0-9]+$ ]] || ! [[ "$START_PORT" =~ ^[0-9]+$ ]]; then
        echo -e "${RED}输入的虚拟IP最后一段、IP数量或端口起始值不是有效的数字。${NC}"
        exit 1
    fi

    # 检查IP段格式是否正确
    if ! [[ "$IP_PREFIX" =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.$ ]]; then
        echo -e "${RED}输入的IP段格式不正确，请输入类似192.168.0.的格式。${NC}"
        exit 1
    fi

    CONFIG_FILE="/root/x-ui面板配置.txt"
    TXT_FILE="/root/ip配置信息.txt"

    cat <<EOF > $CONFIG_FILE
{
  "api": {
    "services": [
      "HandlerService",
      "LoggerService",
      "StatsService"
    ],
    "tag": "api"
  },
  "inbounds": [
    {
      "listen": "127.0.0.1",
      "port": 62789,
      "protocol": "dokodemo-door",
      "settings": {
        "address": "127.0.0.1"
      },
      "tag": "api"
    }
  ],
  "outbounds": [
EOF

    echo "虚拟IP地址 | 端口号 | 公网IP" > $TXT_FILE

    for ((i=0; i<IP_COUNT; i++))
    do
        # 获取当前虚拟IP地址
        CURRENT_IP="${IP_PREFIX}$((START_IP + i))"

        # 生成配置文件名，从eth0:1开始
        NIC_CONFIG_FILE="/etc/sysconfig/network-scripts/ifcfg-${MAIN_NIC}:$((i + 1))"

        # 生成配置文件内容
        cat <<EOF > $NIC_CONFIG_FILE
DEVICE=${MAIN_NIC}:$((i + 1))
BOOTPROTO=static
HWADDR=$MAC_ADDRESS
ONBOOT=yes
IPADDR=$CURRENT_IP
NETMASK=$NETMASK
GATEWAY=$GATEWAY
EOF

        # 启动虚拟网卡
        ifup ${MAIN_NIC}:$((i + 1))

        echo -e "${GREEN}已配置虚拟IP地址: $CURRENT_IP${NC}"

        # 获取对应的公网IP
        PUBLIC_IP=$(curl -s --interface $CURRENT_IP http://ipinfo.io/ip)

        # 检查公网IP是否获取成功
        if [ -z "$PUBLIC_IP" ]; then
            echo -e "${RED}无法获取 $CURRENT_IP 对应的公网IP，请检查网络连接。${NC}"
            PUBLIC_IP="N/A"
        fi

        # 生成x-ui面板配置文件
        cat <<EOF >> $CONFIG_FILE
{"tag":"ip$((i + 1))","sendThrough":"$CURRENT_IP","protocol":"freedom","settings":{}},
EOF

        # 生成TXT文件内容
        echo "$CURRENT_IP | $((START_PORT + i)) | $PUBLIC_IP" >> $TXT_FILE
    done

    # 获取主机自身的公网IP
    SELF_PUBLIC_IP=$(curl -s http://ipinfo.io/ip)

    # 检查公网IP是否获取成功
    if [ -z "$SELF_PUBLIC_IP" ]; then
        echo -e "${RED}无法获取主机自身的公网IP，请检查网络连接。${NC}"
        SELF_PUBLIC_IP="N/A"
    fi

    # 获取主机自身的虚拟IP
    SELF_VIRTUAL_IP=$(ifconfig $MAIN_NIC | grep -w "inet" | awk '{print $2}')

    # 检查虚拟IP是否获取成功
    if [ -z "$SELF_VIRTUAL_IP" ]; then
        echo -e "${RED}无法获取主机自身的虚拟IP，请检查网络配置。${NC}"
        SELF_VIRTUAL_IP="N/A"
    fi

    # 生成x-ui面板配置文件
    cat <<EOF >> $CONFIG_FILE
{"tag":"self","sendThrough":"$SELF_VIRTUAL_IP","protocol":"freedom","settings":{}},
    {
      "protocol": "freedom",
      "settings": {}
    },
    {
      "protocol": "blackhole",
      "settings": {},
      "tag": "blocked"
    }
  ],
  "policy": {
    "system": {
      "statsInboundDownlink": true,
      "statsInboundUplink": true
    }
  },
  "routing": {
    "rules": [
EOF

    for ((i=0; i<IP_COUNT; i++))
    do
        CURRENT_PORT=$((START_PORT + i))
        cat <<EOF >> $CONFIG_FILE
      {"inboundTag":["inbound-$CURRENT_PORT"],"outboundTag":"ip$((i + 1))","type":"field"},
EOF
    done

    # 添加主机自身的配置
    SELF_PORT=$((START_PORT + IP_COUNT))
    cat <<EOF >> $CONFIG_FILE
      {"inboundTag":["inbound-$SELF_PORT"],"outboundTag":"self","type":"field"},
      {
        "inboundTag": [
          "api"
        ],
        "outboundTag": "api",
        "type": "field"
      },
      {
        "ip": [
          "geoip:private"
        ],
        "outboundTag": "blocked",
        "type": "field"
      },
      {
        "outboundTag": "blocked",
        "protocol": [
          "bittorrent"
        ],
        "type": "field"
      }
    ]
  },
  "stats": {}
}
EOF

    # 生成TXT文件内容
    echo "$SELF_VIRTUAL_IP | $SELF_PORT | $SELF_PUBLIC_IP" >> $TXT_FILE

    echo -e "${GREEN}x-ui面板配置文件已生成，路径为: ${PURPLE}$CONFIG_FILE${NC}"
    echo -e "${GREEN}虚拟IP、端口号和公网IP对应关系文件已生成，路径为: ${PURPLE}$TXT_FILE${NC}"

    # 重启网络服务
    echo -e "${YELLOW}正在重启网络服务...${NC}"
    if command -v systemctl &> /dev/null; then
        systemctl restart network
    elif command -v service &> /dev/null; then
        service network restart
    else
        echo -e "${RED}无法找到合适的命令重启网络服务，请手动重启网络服务。${NC}"
        exit 1
    fi

    echo -e "${GREEN}虚拟IP地址配置完成，网络服务已重启。${NC}"

    # 验证每个虚拟IP对应的公网IP是否能ping通
    echo -e "${YELLOW}正在验证每个虚拟IP对应的公网IP是否能ping通...${NC}"
    ALL_PING_SUCCESS=true
    for ((i=0; i<IP_COUNT; i++))
    do
        # 获取当前虚拟IP地址
        CURRENT_IP="${IP_PREFIX}$((START_IP + i))"

        # 获取对应的公网IP
        PUBLIC_IP=$(curl -s --interface $CURRENT_IP http://ipinfo.io/ip)

        # 检查公网IP是否获取成功
        if [ -z "$PUBLIC_IP" ]; then
            echo -e "${RED}无法获取 $CURRENT_IP 对应的公网IP，请检查网络连接。${NC}"
            continue
        fi

        # 尝试ping公网IP，只输出是否能ping通
        ping -c 1 -W 1 $PUBLIC_IP > /dev/null

        if [ $? -ne 0 ]; then
            echo -e "${RED}$CURRENT_IP 对应的公网IP $PUBLIC_IP 无法ping通。${NC}"
            ALL_PING_SUCCESS=false
        fi
    done

    if $ALL_PING_SUCCESS; then
        echo -e "${GREEN}全部ping通。${NC}"
    else
        echo -e "${RED}部分虚拟IP对应的公网IP无法ping通，请检查网络配置。${NC}"
    fi

    echo -e "${GREEN}验证完成。${NC}"
}

# sk5一键配置
function sk5_one_click_setup() {
    echo -e "${YELLOW}正在获取 x-ui 面板信息，请稍候...${NC}"

    # 在后台运行 x-ui 命令并获取输出
    output=$(echo -e "7\n" | x-ui 2>&1)

    # 从输出中提取面板端口、路径、用户名和密码信息
    XUI_PORT=$(echo "$output" | grep -oP '监听端口\[port\]: \K\d+')
    XUI_PATH=$(echo "$output" | grep -oP '根路径\[basePath\]: \K/[^/]+' | sed 's/^.//')
    XUI_USERNAME=$(echo "$output" | grep -oP '用户名\[username\]: \K\w+')
    XUI_PASSWORD=$(echo "$output" | grep -oP '密码\[userpasswd\]: \K\w+')

    # 打印提取的信息
    echo -e "${GREEN}面板信息已获取:${NC}"
    echo -e "${BLUE}面板端口: ${PURPLE}$XUI_PORT${NC}"
    echo -e "${BLUE}根路径: ${PURPLE}$XUI_PATH${NC}"
    echo -e "${BLUE}用户名: ${PURPLE}$XUI_USERNAME${NC}"
    echo -e "${BLUE}密码: ${PURPLE}$XUI_PASSWORD${NC}"
    
    echo -e "${YELLOW}正在登录 x-ui 面板，请耐心等待...${NC}"

    # 获取主机IP
    HOST_IP=$(curl -s http://ipinfo.io/ip)

    # 检查主机IP是否获取成功
    if [ -z "$HOST_IP" ]; then
        echo -e "${RED}无法获取主机IP，请检查网络连接。${NC}"
        exit 1
    fi

    # 定义登录请求的URL
    LOGIN_URL="http://$HOST_IP:$XUI_PORT/$XUI_PATH/login"

    # 定义登录请求头参数
    LOGIN_HEADERS=(
      "Host: $HOST_IP:$XUI_PORT"
      "Connection: keep-alive"
      "Content-Length: 34"
      "Accept: application/json, text/plain, */*"
      "X-Requested-With: XMLHttpRequest"
      "User-Agent: Mozilla/5.0 (Linux; Android 13; 23049RAD8C Build/TKQ1.221114.001) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.5359.128 Mobile Safari/537.36"
      "Content-Type: application/x-www-form-urlencoded; charset=UTF-8"
      "Origin: http://$HOST_IP:$XUI_PORT"
      "Referer: http://$HOST_IP:$XUI_PORT/$XUI_PATH/"
      "Accept-Encoding: gzip, deflate"
      "Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7"
    )

    # 随机生成五位字母数字组合
    generate_random_account() {
      tr -dc 'a-zA-Z0-9' < /dev/urandom | head -c 5
      echo
    }

    # 获取用户输入的sk5账号和密码
    get_sk5_credentials() {
      read -p "请输入sk5用户名（留空随机生成）: " SK5_USER
      read -sp "请输入sk5密码（留空随机生成）: " SK5_PASS
      echo
      if [ -z "$SK5_USER" ]; then
        SK5_USER=$(generate_random_account)
      fi
      if [ -z "$SK5_PASS" ]; then
        SK5_PASS=$(generate_random_account)
      fi
    }

    # 定义后续请求内容正文
    get_data() {
      DATA="up=0&down=0&total=0&remark=$PUBLIC_IP&enable=true&expiryTime=0&autoreset=false&ipalert=false&iplimit=0&listen=$VIRTUAL_IP&port=$SK5_PORT&protocol=socks&settings=%7B%0A%20%20%22auth%22%3A%20%22password%22%2C%0A%20%20%22accounts%22%3A%20%5B%0A%20%20%20%20%7B%0A%20%20%20%20%20%20%22user%22%3A%20%22$SK5_USER%22%2C%0A%20%20%20%20%20%20%22pass%22%3A%20%22$SK5_PASS%22%0A%20%20%20%20%7D%0A%20%20%5D%2C%0A%20%20%22udp%22%3A%20true%2C%0A%20%20%22ip%22%3A%20%22127.0.0.1%22%0A%7D&streamSettings=%7B%0A%20%20%22network%22%3A%20%22tcp%22%2C%0A%20%20%22security%22%3A%20%22none%22%2C%0A%20%20%22tcpSettings%22%3A%20%7B%0A%20%20%20%20%22header%22%3A%20%7B%0A%20%20%20%20%20%20%22type%22%3A%20%22none%22%0A%20%20%20%20%7D%2C%0A%20%20%20%20%22acceptProxyProtocol%22%3A%20false%0A%20%20%7D%0A%7D&sniffing=%7B%7D"
    }

    # 发送登录请求并提取Set-Cookie头中的session值
    login() {
      LOGIN_DATA="username=$XUI_USERNAME&password=$XUI_PASSWORD"
      RESPONSE=$(curl -X POST -H "${LOGIN_HEADERS[@]}" -d "$LOGIN_DATA" "$LOGIN_URL" --insecure -i 2>/dev/null)
      SESSION_COOKIE=$(echo "$RESPONSE" | grep -i 'Set-Cookie:' | sed -n 's/.*session=\([^;]*\).*/\1/p')
      if [ -z "$SESSION_COOKIE" ]; then
        echo -e "${RED}登录失败，请检查x-ui面板登录账号和密码。${NC}"
        return 1
      else
        echo -e "${GREEN}登录成功！${NC}"
        return 0
      fi
    }

    # 更新面板配置
    update_panel_config() {
      # 定义面板配置更新请求的 URL
      UPDATE_URL="http://$HOST_IP:$XUI_PORT/$XUI_PATH/xui/setting/update"

      # 定义请求头参数
      UPDATE_HEADERS=(
        "Host: $HOST_IP:$XUI_PORT"
        "Connection: keep-alive"
        "Content-Length: 3080"  # 将在构建请求体后更新
        "Accept: application/json, text/plain, */*"
        "X-Requested-With: XMLHttpRequest"
        "User-Agent: Mozilla/5.0 (Linux; Android 13; 23049RAD8C Build/TKQ1.221114.001) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.5359.128 Mobile Safari/537.36"
        "Content-Type: application/x-www-form-urlencoded; charset=UTF-8"
        "Origin: http://$HOST_IP:$XUI_PORT"
        "Referer: http://$HOST_IP:$XUI_PORT/$XUI_PATH/xui/setting"
        "Accept-Encoding: gzip, deflate"
        "Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7"
        "Cookie: session=$SESSION_COOKIE"
      )

      # 从指定路径读取 xrayTemplateConfig 内容
      XRAY_TEMPLATE=$(cat /root/x-ui面板配置.txt)

      # 定义 URL 编码函数
      url_encode() {
        local raw_string="$1"
        local encoded_string=""
        for (( i=0; i<${#raw_string}; i++ )); do
          local c="${raw_string:i:1}"
          case "$c" in
            [a-zA-Z0-9.~_-]) encoded_string+="$c" ;;  # 不需要编码的字符
            *) printf -v encoded_string '%s%%%02X' "$encoded_string" "'$c" ;;  # 其他字符编码
          esac
        done
        echo "$encoded_string"
      }

      # 定义请求内容文本
      get_update_data() {
        local update_content="webListen=&webPort=$XUI_PORT&webCertFile=&webKeyFile=&webBasePath=/$XUI_PATH/&tgBotEnable=false&tgBotToken=&tgBotChatId=0&tgRunTime=&xrayTemplateConfig=$(url_encode "$XRAY_TEMPLATE")&tgNotifyExpireTimeDiff=0&tgNotifyTrafficDiff=0&cpulimitNotifyConfig=0&timeLocation=Asia/Shanghai"
        
        echo "$update_content"
      }

      # 获取请求内容
      DATA=$(get_update_data)

      # 更新 Content-Length
      CONTENT_LENGTH=${#DATA}
      UPDATE_HEADERS[2]="Content-Length: $CONTENT_LENGTH"

      # 构建 curl 命令
      CURL_CMD="curl -X POST"

      # 添加请求头参数
      for HEADER in "${UPDATE_HEADERS[@]}"; do
        CURL_CMD+=" -H \"$HEADER\""
      done

      # 添加请求内容和 URL
      CURL_CMD+=" -d \"$DATA\" \"$UPDATE_URL\" --insecure"

      # 执行更新请求的 curl 命令并捕获响应
      RESPONSE=$(eval $CURL_CMD)
      
      # 检查响应结果
      if echo "$RESPONSE" | grep -q '修改设置成功'; then
        echo -e "${GREEN}面板配置更新成功。${NC}"
      else
        echo -e "${RED}面板配置更新失败。${NC}"
      fi
    }

    # 主循环
    while true; do
      if login; then
        break
      else
        read -p "是否重新尝试登录？(y/n): " REPLY
        if [[ ! $REPLY =~ ^[Yy]$ ]]; then
          echo -e "${RED}退出程序。${NC}"
          exit 1
        fi
      fi
    done

    # 获取sk5账号和密码
    get_sk5_credentials

    # 从文件中读取虚拟IP、端口号和公网IP
    CONFIG_FILE="/root/x-ui面板配置.txt"
    TXT_FILE="/root/ip配置信息.txt"

    if [ ! -f "$CONFIG_FILE" ] || [ ! -f "$TXT_FILE" ]; then
      echo -e "${RED}未找到配置文件或IP配置信息文件，请先运行功能3。${NC}"
      exit 1
    fi

    # 读取文件内容
    mapfile -t lines < "$TXT_FILE"

    # 找到有效第一行
    for ((i=0; i<${#lines[@]}; i++)); do
      line="${lines[i]}"
      if [[ "$line" =~ ^[0-9] ]]; then
        start_index=$i
        break
      fi
    done

    # 从有效第一行开始读取
    ip_counter=1
    SK5_INFO_FILE="/root/sk5账号信息.txt"
    > $SK5_INFO_FILE  # 清空文件内容

    for ((i=start_index; i<${#lines[@]}; i++)); do
      line="${lines[i]}"
      VIRTUAL_IP=$(echo "$line" | awk -F'|' '{print $1}' | tr -d ' ')
      SK5_PORT=$(echo "$line" | awk -F'|' '{print $2}' | tr -d ' ')
      PUBLIC_IP=$(echo "$line" | awk -F'|' '{print $3}' | tr -d ' ')

      echo -e "${GREEN}ip$ip_counter：${YELLOW}$PUBLIC_IP${NC} 配置完成"

      # 定义后续请求的URL
      URL="http://$HOST_IP:$XUI_PORT/$XUI_PATH/xui/inbound/add"

      # 获取请求内容
      get_data

      # 更新Content-Length
      CONTENT_LENGTH=${#DATA}

      # 定义后续请求头参数
      HEADERS=(
        "Host: $HOST_IP:$XUI_PORT"
        "Connection: keep-alive"
        "Content-Length: $CONTENT_LENGTH"
        "Accept: application/json, text/plain, */*"
        "X-Requested-With: XMLHttpRequest"
        "User-Agent: Mozilla/5.0 (Linux; Android 13; 23049RAD8C Build/TKQ1.221114.001) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.5359.128 Mobile Safari/537.36"
        "Content-Type: application/x-www-form-urlencoded; charset=UTF-8"
        "Origin: http://$HOST_IP:$XUI_PORT"
        "Referer: http://$HOST_IP:$XUI_PORT/$XUI_PATH/xui/inbounds"
        "Accept-Encoding: gzip, deflate"
        "Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7"
        "Cookie: session=$SESSION_COOKIE"
      )

     # 构建curl命令
      CURL_CMD="curl -X POST"

      # 添加后续请求头参数
      for HEADER in "${HEADERS[@]}"; do
        CURL_CMD+=" -H \"$HEADER\""
      done

      # 添加后续请求内容正文和URL
      CURL_CMD+=" -d \"$DATA\" \"$URL\" --insecure"

      # 执行后续请求的curl命令并重定向输出到/dev/null
      eval "$CURL_CMD > /dev/null 2>&1"
      
      # 记录sk5账号信息
      echo "$PUBLIC_IP|$SK5_PORT|$SK5_USER|$SK5_PASS" >> $SK5_INFO_FILE

      ip_counter=$((ip_counter + 1))
    done

    # 确认更新面板配置
    update_panel_config

    # 重启x-ui面板
    echo -e "${YELLOW}正在重启x-ui面板...${NC}"
    systemctl restart x-ui
    echo -e "${GREEN}x-ui面板重启完成。${NC}"

    # 生成sk5账号信息文件
    echo -e "${GREEN}sk5账号信息文件已生成，路径为: ${PURPLE}$SK5_INFO_FILE${NC}"

    echo -e "${GREEN}sk5一键配置完成。${NC}"
}

# 运行前必要配置（必看）
function pre_run_config() {
    echo -e "${RED}运行前必要配置（必看）：${NC}"
    echo -e "${YELLOW}1. 安全组添加ICMP规则。${NC}"
    echo -e "${YELLOW}2. 防火墙放行54321端口。${NC}"
    echo -e "${YELLOW}3. sk5配置只限第一次有效，重新配置需重装x-ui。${NC}"
}

# 主菜单
function main_menu() {
    while true; do
        echo -e "${BLUE}请选择要执行的功能：${NC}"
        echo -e "${PURPLE}1. 运行前必要配置（必看）${NC}"
        echo -e "${PURPLE}2. x-ui面板一键安装${NC}"
        echo -e "${PURPLE}3. 配置虚拟IP并生成x-ui面板配置文件${NC}"
        echo -e "${PURPLE}4. sk5一键配置${NC}"
        echo -e "${PURPLE}0. 退出脚本${NC}"
        read -p "输入选项编号: " OPTION

        case $OPTION in
            1)
                pre_run_config
                ;;
            2)
                install_x_ui
                ;;
            3)
                configure_vips
                ;;
            4)
                sk5_one_click_setup
                ;;
            0)
                echo -e "${GREEN}退出脚本。${NC}"
                exit 0
                ;;
            *)
                echo -e "${RED}无效选项，请重新选择。${NC}"
                ;;
        esac
    done
}

# 运行主菜单
main_menu